也是記錄一些針對部分功能的小專案,
這篇會是資料庫查詢圖表呈現
,
那前端要做到圖表呈現也有滿多種,
今天主要使用的是Echart
來幫助我們做到資料可視化,
那這篇還會包含記錄到後端連線資料庫的部分。
1.將資料表資訊分開存放於models.py ,使用時才進行匯入
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# PostgreSQL 連接信息
db_host = '***'
db_port = '***'
db_user = '***'
db_password = '***'
db_name = '***'
class ByPcsSummary(Base):
__tablename__ = "by_pcs_summary"
id= Column(Integer, primary_key=True)
Plant= Column(String)
Line= Column(String)
Date= Column(String)
Section= Column(Integer)
AOI_Input= Column(Integer)
AI_Input= Column(Integer)
OKOK= Column(Integer)
NGNG= Column(Integer)
NTF= Column(Integer)
class ByPointSummary(Base):
__tablename__ = "by_point_summary"
id= Column(Integer, primary_key=True)
PositionID=Column(String)
Product= Column(String)
Date= Column(String)
Line= Column(String)
AIModel= Column(Integer)
OKOK= Column(Integer)
NGNG= Column(Integer)
Total= Column(Integer)
NTF= Column(Integer)
2.後端部分使用sqlalchemy連線資料庫進行查詢
# 創建 SQLAlchemy 引擎
db_url = f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}"
engine = create_engine(db_url)
# 定義 ORM 映射
Base = declarative_base()
# 創建一個 Session 類型以進行數據庫交互
Session = sessionmaker(bind=engine)
3.查詢後將資料轉換為json格式回傳網頁
@chart.route('/pcs_query', methods=['GET','POST'])
def pcs_query_data():
date = request.form.get('date')
line = request.form.get('line')
# 創建一個會話對象
session = Session()
# 執行查詢
query_result = session.query(ByPcsSummary.id,ByPcsSummary.Plant,ByPcsSummary.Line,ByPcsSummary.Date,\
ByPcsSummary.Section,ByPcsSummary.AOI_Input,ByPcsSummary.AI_Input,ByPcsSummary.OKOK,ByPcsSummary.NGNG,ByPcsSummary.NTF) \
.filter(ByPcsSummary.Date == date,ByPcsSummary.Line == line)\
.order_by(ByPcsSummary.id).limit(150).all()
# 關閉
session.close()
# 將查詢結果轉換為 JSON 格式
result = [
{
'Plant': row.Plant,
'ID': row.id,
'Section': row.Section,
'AOI_Input': row.AOI_Input,
'AI_Input': row.AI_Input,
'NTF': row.NTF,
'OKOK': row.OKOK,
'NGNG': row.NGNG
}
for row in query_result
]
return render_template('chart_pcs.html', result=result,date=date,line=line)
@chart.route('/point_query', methods=['GET','POST'])
def point_query_data():
date = request.form.get('date')
line = request.form.get('line')
# 創建一個會話對象
session = Session()
# 執行查詢
query_result = session.query(ByPointSummary.PositionID,ByPointSummary.Product,ByPointSummary.Line,ByPointSummary.AIModel,\
ByPointSummary.NTF,ByPointSummary.NGNG,ByPointSummary.OKOK,ByPointSummary.Total) \
.filter(ByPointSummary.Date == date,ByPointSummary.Line == line)\
.order_by(ByPointSummary.id).limit(150).all()
# 關閉
session.close()
# 將查詢結果轉換為 JSON 格式
result = [
{
'PositionID': row.PositionID,
'Product': row.Product,
'Line': row.Line,
'AIModel': row.AIModel,
'NTF': row.NTF,
'OKOK': row.OKOK,
'NGNG': row.NGNG,
'Total': row.Total
}
for row in query_result
]
return render_template('chart_point.html', result=result,date=date,line=line)
4.使用map函數從data數組中提取值存放
5.設定圖表的欄位及各項配置
6.寫進圖表所使用的各項值
Chart_pcs.html
<div class="container mt-3">
<div id="chart" style="height: 350px"></div>
</div>
<script type="text/javascript">
var data = {{ result | safe}};
var aiInputValues = data.map(function (item) {
return item.AI_Input;
});
var aoiInputValues = data.map(function (item) {
return item.AOI_Input;
});
var ngngValues = data.map(function (item) {
return item.NGNG;
});
var okokValues = data.map(function (item) {
return item.OKOK;
});
var plantValues = data.map(function (item) {
return item.Plant;
});
var sectionValues = data.map(function (item) {
return item.Section;
});
var ID = data.map(function (item) {
return item.ID;
});
// 創建 ECharts 選項
var option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
var dataIndex = params[0].dataIndex;
var tooltipText = 'Section: ' + sectionValues[dataIndex] + '<br>';
tooltipText += 'ID: ' + ID[dataIndex] + '<br>';
tooltipText += 'Plant: ' + plantValues[dataIndex] + '<br>';
params.forEach(function (param) {
tooltipText += param.seriesName + ': ' + param.value + '<br>';
});
return tooltipText;
}
},
legend: {
data: ['AI_Input', 'AOI_Input', 'NGNG', 'OKOK']
},
xAxis: {
type: 'category',
data: sectionValues
},
yAxis: [
{
type: 'value',
name: 'AI_Input & AOI_Input',
position: 'left',
axisLabel: {
formatter: '{value}'
}
},
{
type: 'value',
name: 'NGNG & OKOK',
position: 'right',
axisLabel: {
formatter: '{value}'
}
}
],
series: [
{
name: 'AI_Input',
type: 'bar',
data: aiInputValues
},
{
name: 'AOI_Input',
type: 'bar',
data: aoiInputValues
},
{
name: 'NGNG',
type: 'line',
yAxisIndex: 1, // 使用右側的 Y 軸
data: ngngValues
},
{
name: 'OKOK',
type: 'line',
yAxisIndex: 1, // 使用右側的 Y 軸
data: okokValues
}
]
};
// 初始化 ECharts 圖表
var dom = document.getElementById('chart');
var myChart = echarts.init(dom);
if (option && typeof option === 'object') {
myChart.setOption(option);
}
</script>
chart_point.html
<div class="container mt-3">
<div id="chart" style="height: 350px"></div>
</div>
<script type="text/javascript">
var data = {{ result | safe }};
var AIModelValues = data.map(function (item) {
return item.AIModel;
});
var NTFValues = data.map(function (item) {
return item.NTF;
});
var ngngValues = data.map(function (item) {
return item.NGNG;
});
var okokValues = data.map(function (item) {
return item.OKOK;
});
var ProductValues = data.map(function (item) {
return item.Product;
});
var TotalValues = data.map(function (item) {
return item.Total;
});
var PositionID = data.map(function (item) {
return item.PositionID;
});
// 創建 ECharts 選項
var option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
var dataIndex = params[0].dataIndex;
var tooltipText = 'PositionID: ' + PositionID[dataIndex] + '<br>';
tooltipText += 'Product: ' + ProductValues[dataIndex] + '<br>';
params.forEach(function (param) {
tooltipText += param.seriesName + ': ' + param.value + '<br>';
});
return tooltipText;
}
},
legend: {
data: ['AIModel', 'NTF', 'NGNG', 'OKOK','Total']
},
xAxis: {
type: 'category',
data: PositionID
},
yAxis: [
{
type: 'value',
name: 'AIModel & NTF',
position: 'left',
axisLabel: {
formatter: '{value}'
}
},
{
type: 'value',
name: 'NGNG & OKOK & Total',
position: 'right',
axisLabel: {
formatter: '{value}'
}
}
],
series: [
{
name: 'AIModel',
type: 'bar',
data: AIModelValues
},
{
name: 'NTF',
type: 'bar',
data: NTFValues
},
{
name: 'NGNG',
type: 'line',
yAxisIndex: 1, // 使用右側的 Y 軸
data: ngngValues
},
{
name: 'OKOK',
type: 'line',
yAxisIndex: 1, // 使用右側的 Y 軸
data: okokValues
},
{
name: 'Total',
type: 'line',
yAxisIndex: 1, // 使用右側的 Y 軸
data: TotalValues
}
]
};
// 初始化 ECharts 圖表
var dom = document.getElementById('chart');
var myChart = echarts.init(dom);
if (option && typeof option === 'object') {
myChart.setOption(option);
}
</script>
本篇主要記錄小功能的部分程式碼重點,
若有用到相同功能可以依照程式碼做參考去撰寫~